package xjtu.sad.zbsj.util;


import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import xjtu.sad.zbsj.common.Result;
import xjtu.sad.zbsj.common.Utils;
import xjtu.sad.zbsj.dao.labelTask.LabelTaskDao;
import xjtu.sad.zbsj.dao.util.UtilDao;
import xjtu.sad.zbsj.task.annotater.labelTask.TaskInfo;
import xjtu.sad.zbsj.template.UserInfo;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

@RestController
@RequestMapping("/")
public class UtilAPI {

    @Resource
    private UtilDao utilDao;

    @Resource
    private LabelTaskDao labelTaskDao;

    @Resource
    private UtilService utilService;

    private static String baseUrl;

    // 获取当前的基础路径,如果是win则是IMG_PATH_WIN,如果是linux则是IMG_PATH_LIN
    public UtilAPI() {
        baseUrl = Utils.getImgPrefix();
    }

    /**
     * 根据登录用户获得该用户可访问的所有菜单
     *
     * @param userId 用户id
     * @return 可访问的菜单列表
     */
    @GetMapping("/menu/getMenu")
    public Result getMenu(@RequestParam Integer userId) {
        UserInfo userInfo = utilDao.getUserInfo(userId);
        if (userInfo != null) {
            List<MenuItem> menuItemList = utilService.getMenuList(userInfo.getRoleId());
            return Result.success(menuItemList);
        } else {
            return Result.fail(Result.ERR_CODE_UNLOGIN, "获取菜单栏失败,请检查登录状态");
        }
    }

    @GetMapping("/getLabelResult")
    public void exportLabelResult(Integer taskId, HttpServletResponse resp) {
        TaskInfo taskInfo = labelTaskDao.getTaskInfo(taskId);
        System.out.println(taskInfo);

        // 首先先判断该任务是否已经标注审核完成,即状态是否为已完成(4)
        if (taskInfo.getTaskStatus() != 4) {
            return;
        }

        // 需要判断原来是否已经生成了导出文件,如果生成的话直接返回,如果没有需要生成结果文件
        String path = baseUrl + "/result/";
        String fileName = taskInfo.getFileName();
        if (fileName == null || "".equals(fileName)) {
            // 生成数据文件
            // TODO:按理说这块应该是另外一个线程中的,不知道怎么处理
            fileName = utilService.generateOutPutFile(taskInfo, path);
        }

        // 返回数据文件
        resp.setContentType("application/octet-stream");
        resp.setHeader("Content-Disposition", "attachment;fileName=" + fileName);

        outPut(path, fileName, resp);
    }


    /**
     * 上传文件
     *
     * @param request  请求头
     * @param file     需要保存的文件
     * @param response 响应头
     * @param taskId   任务id
     * @param type     任务类型,限img,video,audio,text
     * @return 上传结果
     */
    @PostMapping("/uploadFile")
    public Result uploadZipFile(HttpServletRequest request, MultipartFile file, HttpServletResponse response, @RequestParam Integer taskId, @RequestParam String type) {

        String fileName = file.getOriginalFilename();
        String path = baseUrl + "/" + type + "/";// 解压目标文件夹
        File dir = new File(path);
        dir.mkdirs();
        String filePath = baseUrl + "/zip/";// 压缩包存放文件夹
        File fileDir = new File(filePath);
        fileDir.mkdirs();
        File saveFile = new File(fileDir, fileName);//将压缩包解析到指定位置
        try {
            file.transferTo(saveFile);
            String newFilePath = filePath + fileName;
            File zipFile = new File(newFilePath);
            utilService.unZipFiles(zipFile, path, taskId);//解压文件，获取文件路径

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("解压执行失败");
        }
        //程序结束时，删除临时文件
//        utilService.deleteFiles(filePath);//删除压缩包文件夹
//        utilService.deleteFiles(path);//删除解压文件夹

        return Result.success("上传成功");
    }


    /**
     * 获取视频内容
     *
     * @param fileName 视频文件名称
     * @param resp     返回体
     */
    @GetMapping("/video")
    public void getVideo(String fileName, HttpServletResponse resp) {
        String path = baseUrl + "/video/";
        outPut(path, fileName, resp);
    }

    /**
     * 获得图片内容
     *
     * @param fileName 文件名称
     * @param resp     返回体
     */
    @GetMapping("/img")
    public void getImg(String fileName, HttpServletResponse resp) {
        String path = baseUrl + "/img/";
        outPut(path, fileName, resp);
    }

    /**
     * 获得音频内容
     *
     * @param fileName 文件名称
     * @param resp     返回体
     */
    @GetMapping("/audio")
    public void getAudio(String fileName, HttpServletResponse resp) {
        String path = baseUrl + "/audio/";
        outPut(path, fileName, resp);
    }


    /**
     * 将指定路径的文件发送到浏览器中
     *
     * @param path     文件路径
     * @param fileName 文件名称
     * @param resp     返回体
     */
    private void outPut(String path, String fileName, HttpServletResponse resp) {
        try {
            //读取文件的输入流
            InputStream in = new FileInputStream(path + fileName);
            //将文件信息输出到浏览器的输出流
            OutputStream out = resp.getOutputStream();

            byte[] b = new byte[10240];//容量为10240字节的缓存区
            int len;//从输入流读取并放入缓存区的数据量

            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
            out.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
